import Dingo.API as api
import random

__author__ = "Sarah Mount"

class TheSimulation(api.Simulation):
	def __init__(self, graph):
		ether = api.Ether(self)
		num_nodes = 50
		sensors = (CommunicatingSensor(graph, ether, i, num_nodes) for i in xrange(num_nodes))
		api.Simulation.__init__(self, sensors, graph)
	def run(self):
		super(TheSimulation, self).run()
	
class CommunicatingSensor(api.Sensor):
	def __init__(self, graph, ether, i, num_nodes):
		x = random.randrange(400)
		y = random.randrange(500)
		api.Sensor.__init__(self, graph, "Sensor%d" % i, (x, y), api.SensorColor.Grey, 
				api.Scheduler([SendTask(self, num_nodes), RecvTask(self)], -1), ether)
		return

class ColourPacket(api.Packet):
	"""Defines packets to be sent across the network.
	This one just sends sensor colours. When a sensor receives
	a message, it should change colour according to the message
	it's received.
	"""
	def __init__(self, sender_id, receiver_id, msg):#, ether):
		### sending node, receiving node, message_object
		### the message can be anything you like
		api.Packet.__init__(self, sender_id, receiver_id, msg)
		return

class SendTask(api.Task):
	def __init__(self, sensor, num_nodes):
		# self, priority, repetitions, ref-to-sensor
		api.Task.__init__(self, 0, 0, sensor)
		self.num_nodes = num_nodes
	def task(self):
		### Note how hacky this is!!
		### Nodes should really get a list of IDs by broadcasting
		### to the network first (I'll give you code for that l8r)		
		self.receiver_id = "Sensor%d" % random.randint(0, self.num_nodes-1)
		# Don't send anything to yourself!
		while (self.receiver_id == self.sensor.id):
			self.receiver_id = "Sensor%d" % random.randint(0, self.num_nodes-1)
		### Real work
		rgb = random.randrange(1<<24)
		msg = api.SensorColor.FromRGBCombined(rgb)
		packet = ColourPacket(self.sensor.id, self.receiver_id, msg)#, self.sensor.ether)
		### Put packet on send queue		
		self.sensor.send_q.put(packet) 
		### Send next packet in queue with arc colour
		self.sensor.send(api.SensorColor.FromName("Grey"))  
		### Sleeeeep
		sleeptime = random.uniform(1, 2)
		api.Sleep(sleeptime)
		return

class RecvTask(api.Task):
	def __init__(self, sensor):
		# self, priority, repetitions, ref-to-sensor
		api.Task.__init__(self, 1, 0, sensor)
	def task(self):
		### Debug info
		node = self.sensor.node # graphical sensor
		node.SetAvatarColour(api.SensorColor.FromName("Black"))
		### Real work
		while not self.sensor.recv_q.empty(): # If there are any messages
			msg = self.sensor.recv_q.get()
			node.SetAvatarColour(msg.msg)
			# DEBUG info --- USE THE PACKET LOGGER!
			#print_info = (msg.sender_id, msg.receiver_id, msg.time_sent, msg.rssi)
			#print "Packet from %s to %s sent at time %.3f has RSSI = %f" % print_info
		### Sleeep
		sleeptime = random.uniform(1, 2)
		api.Sleep(sleeptime)
